# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   File Name：     BasePage.py
   Description :
   Author :        ZhangYiLin
   date：          2020/12/07 15:20
-------------------------------------------------
   Change Activity:
                   2020/12/07 15:20
-------------------------------------------------
"""
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.wait import WebDriverWait as wd
from selenium.common.exceptions import (
    TimeoutException, NoAlertPresentException)
# from selenium.webdriver import ActionChains
# from selenium.webdriver.common.keys import Keys

from common.Clipboard import ClipBoard
from common.Keyboard import KeyBoard
from config.ConfigHost import ConfHost

from common.NewLoguru import global_log


class BasePage:
    """
    页面对象封装
    """
    def __init__(self, driver, timeout=30):
        self.byDic = {
            'id': By.ID,
            'name': By.NAME,
            'class_name': By.CLASS_NAME,
            'xpath': By.XPATH,
            'link_text': By.LINK_TEXT
        }
        self.driver = driver
        self.timeout = timeout
        self.url = ConfHost().get_host()

    def open_url(self):
        """
        打开项目地址
        该地址在配置文件中
        """
        global_log.debug('打开网页：{}'.format(self.url))
        self.driver.get(self.url)

    def get_current_url(self):
        """
        延时一秒后获取当前页面url
        """
        time.sleep(1)
        __url = self.driver.current_url
        global_log.debug('当前页面url: {}'.format(__url))
        return __url

    def find_element(self, by, locator):
        """
        单独寻找元素
        :param by: eg: id, name, xpath, css.....
        :param locator: id, name, xpath for str
        :return:
        """
        try:
            global_log.debug(
                'Starting find the element "{}" by "{}"!'.format(
                    locator, by))
            element = wd(
                self.driver,
                self.timeout).until(
                lambda x: x.find_element(
                    by,
                    locator))
        except TimeoutException as t:
            global_log.error('found "{}" timeout!  {}'.format(locator, t))
        else:
            return element

    def find_elements(self, by, locator):
        """
        查找组元素
        :param by: eg: id, name, xpath, css.....
        :param locator: eg: id, name, xpath for str
        :return: elements object
        """
        try:
            global_log.debug(
                'start find the elements "{}" by "{}"!'.format(
                    locator, by))
            elements = wd(
                self.driver,
                self.timeout).until(
                lambda x: x.find_elements(
                    by,
                    locator))
        except TimeoutException as t:
            global_log.error('found "{}" timeout!  {}'.format(locator, t))
        else:
            return elements

    def is_element_exist(self, by, locator):
        """
        判断元素是否存在
        :param by: eg: id, name, xpath, css.....
        :param locator: eg: id, name, xpath for str
        :return: if element return True else return false
        """
        if by.lower() in self.byDic:
            try:
                wd(self.driver, self.timeout). until(
                    ec.visibility_of_element_located((self.byDic[by], locator)))
            except TimeoutException:
                global_log.error('element "{}" not exist'.format(locator))
                return False
            return True
        else:
            global_log.debug('the "{}" error!'.format((by + locator)))

    def is_click(self, by, locator):
        """
        判断页面元素是否可点击
        """
        if by.lower() in self.byDic:
            try:
                element = wd(
                    self.driver, self.timeout). until(
                    ec.element_to_be_clickable(
                        (self.byDic[by], locator)))
            except TimeoutException as e:
                global_log.error("查找{}，报错：{}".format((by + locator), str(e)))
            else:
                return element
        else:
            global_log.error('the "{}" error!'.format(by))

    def is_alert(self):
        """
        assert alert if exit
        :return: alert obj
        """
        try:
            re = wd(self.driver, self.timeout).until(ec.alert_is_present())
        except (TimeoutException, NoAlertPresentException):
            global_log.error("no found alert")
        else:
            return re

    def switch_to_frame(self, by, locator):
        """
        判断frame是否存在，存在就跳到frame
        :param by:
        :param locator:
        :return:
        """
        global_log.debug('switching to iframe "{}"'.format(locator))
        if by.lower() in self.byDic:
            try:
                wd(self.driver, self.timeout). until(
                    ec.frame_to_be_available_and_switch_to_it((self.byDic[by], locator)))
            except TimeoutException as t:
                global_log.error(
                    'found "{}" timeout！切换frame失败! {}'.format(
                        locator, t))
        else:
            global_log.error('the "{}" error!'.format(by))

    def switch_to_default_frame(self):
        """
        返回默认的frame
        :return:
        """
        global_log.debug('switch back to default iframe')
        try:
            self.driver.switch_to.default_content()
        except Exception as e:
            global_log.error(str(e))

    def get_alert_text(self):
        """
        获取alert的提示信息
        :return:
        """
        alert = self.is_alert()
        if alert:
            return alert.text
        else:
            return None

    def get_element_text(self, by, locator, name=None):
        """
        获取某一个元素的text信息
        :param by:
        :param locator:
        :param name:
        :return:
        """
        try:
            element = self.find_element(by, locator)
            if name:
                return element.get_attribute(name)
            else:
                return element.text
        except AttributeError:
            global_log.error(
                'get "{}" text failed return None'.format(locator))

    def load_url(self, url):
        """
        加载url
        :param url:
        :return:
        """
        js = "window.open('{}')".format(url)
        self.driver.execute_script(js)
        global_log.debug('string upload url "{}"'.format(url))
        return self.driver

    def get_source(self):
        """
        获取页面源码
        :return:
        """
        __source = self.driver.page_source
        global_log.debug('当前页面源码： {}'.format(__source))
        return __source

    def send_keys(self, value, by, locator):
        """
        写数据
        :param by:
        :param locator:
        :param value:
        :return:
        """
        global_log.debug('input "{}"'.format(value))
        try:
            element = self.find_element(by, locator)
            element.send_keys(value)
        except AttributeError as e:
            global_log.error(str(e))

    def clear(self, by, locator):
        """
        清理数据
        :param by:
        :param locator:
        :return:
        """
        global_log.debug('clearing value')
        try:
            element = self.find_element(by, locator)
            element.clear()
        except AttributeError as e:
            global_log.error(str(e))

    def click(self, by, locator):
        """
        点击某个元素
        :param by:
        :param locator:
        :return:
        """
        global_log.debug('click "{}", by {}'.format(locator, by))
        element = self.is_click(by, locator)
        if element:
            element.click()
        else:
            global_log.error('"{}" Can\'t click!'.format((by + locator)))

    @staticmethod
    def sleep(num=0):
        """
        强制等待
        :param num:
        :return:
        """
        global_log.debug('sleep "{}" s'.format(num))
        time.sleep(num)

    def ctrl_v(self, value):
        """
        ctrl + V 粘贴
        :param value:
        :return:
        """
        global_log.debug('粘贴 "{}"'.format(value))
        ClipBoard.set_text(value)
        global_log.debug('sleep 3 s')
        self.sleep(3)
        KeyBoard.two_keys('ctrl', 'v')

    @staticmethod
    def enter_key():
        """
        enter 回车键
        :return:
        """
        global_log.debug('keydown enter')
        KeyBoard.one_key('enter')

    def wait_element_to_be_located(self, by, locator):
        """
        显示等待某个元素出现，且可见
        :param by:
        :param locator:
        :return:
        """
        global_log.debug('waiting "{}" to be located'.format(locator))
        try:
            return wd(
                self.driver, self.timeout).until(
                ec.presence_of_element_located(
                    (self.byDic[by], locator)))
        except TimeoutException as t:
            global_log.error('found "{}" timeout！ {}'.format(locator, t))

    def get_page_source(self):
        """
        获取页面源码
        """
        return self.get_source()


if __name__ == "__main__":
    pass
